/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.devs.benchmark.topology;

import org.devs.benchmark.Util;
import org.devs.benchmark.modeling.CoupledType;
import org.devs.benchmark.modeling.ModelType;

/**
 *
 * @author Alejandro Moreno
 */
public class Tree extends Network {

    int width;
    int height;

    public Tree(String name, int width, int height, Class message, int recursion) throws Exception {
        super(name, message, recursion);

        if (width < 1 || height < 1 || recursion < 1) {
            throw new Exception("Parameters are incorrect");
        }

        this.width = width;
        this.height = height;

    }

    public Tree(String name, int width, int height, Class message) throws Exception {
        super(name, message);

        if (width < 1 || height < 1) {
            throw new Exception("Parameters are incorrect");
        }

        this.width = width;
        this.height = height;

    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }



    public void buildModel() {

        super.setModel(this.createTreeNetwork(this.name, this.height, this.width, super.message, super.recursion));

    }

    public void connectTreeNodes(CoupledType coupled, int height, int width) {


        if (coupled.getModels().size() > 0) {

            for (int i = 0; i < coupled.getModels().get(0).getInports().size(); i++) {
                addConnectionFromParent(coupled, 0, i, i);
                addConnectionToParent(coupled, 0, i, i);
            }

            int count = 1;
            for (int i = 0; i < Util.nNodes(height - 1, width); i++) {

                for (int j = 0; j < width; j++) {

                    addConnection(coupled, i, j, count, j + 1);
                    addConnection(coupled, count, j + 1, i, j);
                    count++;
                }


            }

        }

    }

    public ModelType createTreeNetwork(String name, int height, int length, Class message, int recursion) {
        return createTree(name, height, length, "", message, recursion);
    }

    public ModelType createTree(String name, int height, int width, String id, Class message, int recursion) {

        CoupledType coupled = null;

        if (recursion > 0) {

            coupled = new CoupledType(name + "_Coupled" + id, Util.createInports(width + 1, message), Util.createOutports(width + 1, message));


            for (int j = 0; j < Util.nNodes(height, width); j++) {

                coupled.getModels().add(createTree(name, height, width, id + "_" + j, message, recursion - 1));

            }

            connectTreeNodes(coupled, height, width);


        } else {


            coupled = buildNode(name, width + 1, message, id);



        }


        return coupled;
    }
}
